﻿using UnityEngine;
using UnityEngine.Playables;

namespace GameDesigner
{
    public class TimelineStateMachine : IAnimationHandler
    {
        private Animator animator;
        private PlayableDirector director;
        private float elapsedTime;
        private float normalizedTime;
        private int stateHash;

        public TimelineStateMachine(Animator animator, PlayableDirector director)
        {
            this.animator = animator;
            this.director = director;
        }

        public void SetParams(params object[] args) //中途修改动画对象用
        {
            animator = args[0] as Animator;
            director = args[1] as PlayableDirector;
        }

        public void OnInit()
        {
        }

        public void OnPlayAnimation(State state, StateAction stateAction)
        {
            var clipName = stateAction.clipName;
            stateAction.animTime = 0f;
            if (stateAction.clipAsset != null)
            {
                director.Play(stateAction.clipAsset, DirectorWrapMode.None);
                var playableGraph = director.playableGraph;
                var playable = playableGraph.GetRootPlayable(0);
                playable.SetSpeed(state.animSpeed);
            }
            else
            {
                stateHash = Animator.StringToHash(clipName);
                animator.speed = state.animSpeed;
                elapsedTime = 0f;
                normalizedTime = 0f;
                if (state.isCrossFade)
                    animator.CrossFade(clipName, state.duration);
                else
                    animator.Play(clipName, stateAction.layer, 0f);
            }
        }

        public bool OnAnimationUpdate(State state, StateAction stateAction, StateMachineUpdateMode currMode)
        {
            var isPlaying = true;
            if (stateAction.clipAsset != null)
            {
                var time = director.time;
                var duration = director.duration;
                stateAction.animTime = (float)(time / duration) * 100f;
                isPlaying = director.state == PlayState.Playing;
            }
            else if (currMode == StateMachineUpdateMode.Update)
            {
                elapsedTime += Time.deltaTime * state.animSpeed;
                if (stateAction.length <= 0f)
                {
                    var stateInfo = animator.GetCurrentAnimatorStateInfo(stateAction.layer);
                    if (stateHash == stateInfo.shortNameHash) //当在切换自身状态时, stateInfo获取到的还是上一个动画的状态信息, 所以会导致当前进度错乱, 导致鬼畜问题
                        stateAction.length = stateInfo.length;
                    else
                        return isPlaying; //往下执行就会变成 n/0问题
                }
                normalizedTime = elapsedTime / stateAction.length;
                stateAction.animTime = normalizedTime / 1f * 100f;
            }
            return isPlaying;
        }
    }
}